
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/** @author  John Miller
 *  @version 1.0
 *  @date    Mon Dec 21 15:14:59 EST 2009
 *  @see     LICENSE (MIT style license file).
 */

//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/** This object is used to build the scalation Scala-based Simulation System.
 *  Comment out lines using // for customized builds.  To build the complete
 *  scalation system, type the following two commands:
 *  > scalac Build.scala
 *  > scala Build
 *  Check the file called 'errorlog' for errors generated by any of the
 *  build functions.  Note, this Build object may be replaced with the
 *  Simple Build Tool (sbt) in the future. 
 */
object Build extends App
{
    private val base_dir   = ""
    private val source_dir = base_dir + "src"
    private val class_dir  = base_dir + "classes"
    private val doc_dir    = base_dir + "doc"
    private val ex_dir     = base_dir + "examples"
    private val runsys     = Runtime.getRuntime ()
    private var command    = Array ("")

    /** The packages making up scalation -- comment out (//) for selective builds
     */
    private val packages = Array ("scalation/util",
                                  "scalation/math",
                                  "scalation/linalgebra",
                                  "scalation/linalgebra_gen",
                                  "scalation/calculus",
                                  "scalation/random",
                                  "scalation/stat",
                                  "scalation/scala2d",
                                  "scalation/plot",
                                  "scalation",
                                  "scalation/animation",
                                  "scalation/minima",
                                  "scalation/maxima",
                                  "scalation/analytics",
                                  "scalation/metamodel",
                                  "scalation/queueingnet",
                                  "scalation/dynamics",
                                  "scalation/activity",
                                  "scalation/event",
                                  "scalation/process",
                                  "scalation/state")

    /** The example simulation models -- comment out (//) for selective builds
     */
    private val examples = Array ("dynamics",
                                  "activity",
                                  "event",
                                  "montecarlo",
                                  "process",
                                  "state",
                                  "analytics",
                                  "simopt",
                                  "game")

    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    /** Clear the error log.  The errorlog file shows errors generated any of the
     *  build functions shown below.
     */
    def clearlog
    {
        command = Array ("/bin/sh", "-c", "/bin/date > errorlog")
        runsys.exec(command)
        println (command.deep)
    } // clearlog

    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    /** Start a clean build by removing all old .class files.
     */
    def clean
    {
        for (p <- packages) {
            command = Array ("/bin/sh", "-c", "/bin/rm " + class_dir + "/" + p + "/*.class")
            runsys.exec(command)
            println (command.deep)
        } // for
    } // clean

    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    /** Compile the source files (.scala) for all the packages in scalation.
     */
    def compile
    {
        for (p <- packages) {
            command = Array ("/bin/sh", "-c", "scalac -cp " + class_dir + " -d " + class_dir + " " +
                             source_dir + "/" + p + "/*.scala" + " 2>> errorlog")            
            val cmd = Array ("/bin/sh", "-c", "echo ----- " + p + " >> errorlog")
            println (cmd.deep)
            val proccmd = runsys.exec (cmd)
            proccmd.waitFor ()
            val proc = runsys.exec (command)
            proc.waitFor ()
            println (command.deep)
        } // for
    } // compile

    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    /** Compile the source files (.scala) for all the example models.
     */
    def compileEx
    {
        for (e <- examples) {
            val ex = ex_dir + "/" + e
            command = Array ("/bin/sh", "-c", "scalac -cp " + class_dir + " -d " + ex + "/classes " +
                             ex + "/*.scala" + " 2>> errorlog")            
            val proc = runsys.exec (command)
            proc.waitFor ()
            println (command.deep)
        } // for
    } // compileEx

    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    /** Generate scaladoc files for all the scalation packages.
     */
    def doc
    {
        command = Array ("/bin/sh", "-c", "scaladoc -J-mx1024m -cp classes -d " + doc_dir + " " +
                         source_dir + "/" + "scalation/*/*.scala" + " 2>> errorlog")            
        val proc = runsys.exec (command)
        proc.waitFor ()
        println (command.deep)
    } // doc

    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    /** Generate index.html for browsing the source code.
     */
    def genIndexHtml
    {
        command = Array ("/bin/sh", "-c", "scala -cp " + class_dir +
                         " scalation.util.GenIndexHtml 2>> errorlog")
        val proc = runsys.exec (command)
        proc.waitFor ()
        println (command.deep)
    } // genIndexHtml

    // select build functions by moving the comment delimiters (/***, ***/)
    clearlog
    clean
    compile
    compileEx
    genIndexHtml
    doc
/***
***/

} // Build

